﻿using LeRenard.Core.Properties;
using System;

namespace LeRenard
{
    /// <summary>
    /// Helper class for the "ToString()" method.
    /// </summary>
    public class ToStringHelper
    {
        /// <summary>
        /// Returns the value defined in the <paramref name="displayValueSelector"/>, unless the <paramref name="object"/> is null.
        /// </summary>
        /// <typeparam name="TObject">The type of the <paramref name="object"/>.</typeparam>
        /// <param name="object">The object to generate a display value for, this object is fed to the <paramref name="displayValueSelector"/>.</param>
        /// <param name="displayValueSelector"><see cref="Expression"/> that defines how the value will be presented.</param>
        /// <returns>The result of the <paramref name="displayValueSelector"/> or <see cref="Resources.STR_FMT_NULL"/> when <paramref name="object"/> is null, or <see cref="Resources.STR_FMT_EXCEPTION"/> when <paramref name="displayValueSelector"/> caused an exception.</returns>
        public static string For<TObject>(TObject @object, Func<TObject, string> displayValueSelector)
        {
            try {
                if(@object == null || displayValueSelector == null) {
                    return Resources.STR_FMT_NULL;
                }

                return displayValueSelector.Invoke(@object);
            } catch(Exception ex) {
                return Resources.STR_FMT_EXCEPTION.FormatWith(ex.GetType().ToFriendlyName());                      
            }
        }

        /// <summary>
        /// Performs the ToString() method call on the given <paramref name="object"/>.
        /// </summary>
        /// <typeparam name="TObject">The type of the <paramref name="object"/>.</typeparam>
        /// <param name="object">The object to perform a ToString() method call on.</param>
        /// <returns>The result of the .ToString() method call, or <see cref="Resources.STR_FMT_NULL"/> when <paramref name="object"/> is null.</returns>
        public static string For<TObject>(TObject @object)
        {
            return For<TObject>(@object, o => o.ToString());
        }
    }
}
